package com.samehope.ar.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.samehope.ar.constant.DelFlagEnum;
import com.samehope.ar.constant.IsTempEnum;
import com.samehope.ar.constant.TaskTypeEnum;
import com.samehope.ar.dto.*;
import com.samehope.ar.entity.PatrolRoute;
import com.samehope.ar.entity.PatrolTaskPlan;
import com.samehope.ar.mapper.PatrolTaskPlanMapper;
import com.samehope.ar.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.samehope.ar.util.SessionUtil;
import com.samehope.ar.vo.PaginationDataVO;
import com.samehope.ar.vo.PatrolTaskPlanDetailVO;
import com.samehope.ar.vo.PatrolTaskPlanWeekDetailVO;
import com.samehope.ar.vo.TaskTimeVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 巡检计划任务 服务实现类
 * </p>
 *
 * @author Zhang Luo
 * @since 2019-12-23
 */
@Slf4j
@Service
public class PatrolTaskPlanServiceImpl extends ServiceImpl<PatrolTaskPlanMapper, PatrolTaskPlan> implements IPatrolTaskPlanService {

    @Autowired
    private IPatrolRouteService patrolRouteService;

    @Autowired
    private IPatrolRoutePointService patrolRoutePointService;

    @Autowired
    private ITaskNormalService taskNormalService;

    @Autowired
    private ITaskRouteService taskRouteService;

    @Autowired
    private ITaskPointService taskPointService;

    @Autowired
    private ITaskItemService taskItemService;

    @Autowired
    private ITaskItemChildService taskItemChildService;

    @Override
    public PaginationDataVO<PatrolTaskPlanDetailVO> findByParam(PaginationParam paginationParam, PatrolTaskPlanQueryParam param){
        Page<PatrolTaskPlanDetailVO> page = new Page<>(paginationParam.getPageNum(), paginationParam.getPageSize());
        List<PatrolTaskPlanDetailVO> patrolTaskPlanDetailVOS = this.baseMapper.findByParam(
                 page
                ,SessionUtil.getCompanyId()
                ,SessionUtil.getProjectId()
                ,param.getTeamId()
                ,param.getUserId()
                ,param.getStartDate()
                ,param.getEndDate()
                ,param.getTaskName()
                ,param.getTaskType()
                );
        page.setRecords(patrolTaskPlanDetailVOS);
        return PaginationDataVO.of(page);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(PatrolTaskPlanAddParam param){
        Long companyId = SessionUtil.getCompanyId();
        Long projectId = SessionUtil.getProjectId();
//        PatrolTaskPlan entity = this.baseMapper.findByTaskPlanName(companyId
//                                                                   , projectId
//                                                                   ,null
//                                                                   , param.getTaskNo()
//                                                                   , null);
//        if (entity != null) {
//            throw new IllegalArgumentException("任务编号已存在");
//        }
        PatrolTaskPlan entity = this.baseMapper.findByTaskPlanName(  companyId
                                                    , projectId
                                                    ,null
                                                    ,null
                                                    , param.getTaskName());
        if (entity != null) {
            throw new IllegalArgumentException("任务名称已存在");
        }

        if(param.getTaskType() == TaskTypeEnum.CYCLE.getCode()){
            if(StrUtil.isBlank(param.getExecWeek())){
                throw new IllegalArgumentException("执行日不可为空");
            }
        }else{
            param.setExecWeek(DateUtil.dayOfWeek(DateUtil.parseDate(param.getStartDate()))+"");
        }

        //增加临时线路逻辑
        if(null == param.getRouteId()) {
            RouteAndParam routeAndParam = new RouteAndParam();
            routeAndParam.setRouteName(projectId + "-"  + param.getTaskName() + "-临时线路");
            routeAndParam.setIsTemp(IsTempEnum.TEMP.getCode());
            if (StringUtils.isBlank(param.getPointIds())) {
                throw new IllegalArgumentException("请选择巡检点");
            }
            String[] points = param.getPointIds().split(",");
            List<RoutePointParam> lists = new ArrayList<RoutePointParam>();
            for (int i = 0;i < points.length; i++){
                RoutePointParam pointParam = new RoutePointParam();
                pointParam.setPointId(Long.valueOf(points[i]));
                pointParam.setSortNo(Long.valueOf(i+1));
                lists.add(pointParam);
            }
            routeAndParam.setPoints(lists);
            Long routeId = patrolRouteService.add(routeAndParam);
            param.setRouteId(routeId);
        }

        entity = new PatrolTaskPlan();
        entity.setCompanyId(companyId);
        entity.setProjectId(projectId);
//        entity.setTaskNo(param.getTaskNo());
        entity.setTaskName(param.getTaskName());
        entity.setExecCount(param.getExecCount());
        entity.setExecWeek(param.getExecWeek());
        entity.setRouteId(param.getRouteId());
        entity.setTaskType(param.getTaskType());
        entity.setStartDate(param.getStartDate());
        entity.setEndDate(param.getEndDate());
        entity.setTeamId(param.getTeamId());
        entity.setExecBys(param.getExecBys());
        entity.setExecStartTime(param.getExecStartTime());
        entity.setExecEndTime(param.getExecEndTime());
        entity.setRemarks(param.getRemarks());
        entity.setIsRecordLocation(param.getIsRecordLocation());
        entity.setCreateBy(SessionUtil.getUserId());
        this.save(entity);

        createTask(entity, false);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(PatrolTaskPlanUpdateParam param){
        Long companyId = SessionUtil.getCompanyId();
        Long projectId = SessionUtil.getProjectId();

        QueryWrapper<PatrolTaskPlan> wrapper = new QueryWrapper<>();
        PatrolTaskPlan data = new PatrolTaskPlan();
        data.setDelFlag(DelFlagEnum.NORMAL.getCode());
        data.setCompanyId(companyId);
        data.setProjectId(projectId);
        data.setId(param.getId());
        wrapper.setEntity(data);

        PatrolTaskPlan entity = this.getOne(wrapper);
        if (entity == null) {
            throw new IllegalArgumentException("任务不存在");
        }

//        entity = this.baseMapper.findByTaskPlanName(companyId
//                , projectId
//                , param.getId()
//                , param.getTaskNo()
//                , null);
//        if (entity != null) {
//            throw new IllegalArgumentException("任务编号已存在");
//        }
        entity = this.baseMapper.findByTaskPlanName(  companyId
                , projectId
                ,param.getId()
                ,null
                , param.getTaskName());
        if (entity != null) {
            throw new IllegalArgumentException("任务名称已存在");
        }

        if(param.getTaskType() == TaskTypeEnum.CYCLE.getCode()){
            if(StrUtil.isBlank(param.getExecWeek())){
                throw new IllegalArgumentException("执行日不可为空");
            }
        }else{
            param.setExecWeek("");
        }

        //增加临时线路逻辑
        if(null == param.getRouteId()) {
            throw new IllegalArgumentException("请选择线路/巡检点");
        }else{
            PatrolRoute patrolRoute = patrolRouteService.getById(param.getRouteId());
            if(patrolRoute.getIsTemp() == IsTempEnum.TEMP.getCode()){
                RouteUpdateParam routeUpdateParam = new RouteUpdateParam();
                routeUpdateParam.setIsTemp(IsTempEnum.TEMP.getCode());
                routeUpdateParam.setRouteName(projectId + "-" + param.getTaskName() + "-临时线路");
                if (StringUtils.isBlank(param.getPointIds())) {
                    throw new IllegalArgumentException("请选择巡检点");
                }
                String[] points = param.getPointIds().split(",");
                List<RoutePointParam> lists = new ArrayList<RoutePointParam>();
                for (int i = 0;i < points.length; i++){
                    RoutePointParam pointParam = new RoutePointParam();
                    pointParam.setPointId(Long.valueOf(points[i]));
                    pointParam.setSortNo(Long.valueOf(i+1));
                    lists.add(pointParam);
                }
                routeUpdateParam.setRouteId(param.getRouteId());
                routeUpdateParam.setPoints(lists);
                patrolRouteService.update(routeUpdateParam);
            }
        }

        entity = new PatrolTaskPlan();
        entity.setId(param.getId());
        entity.setCompanyId(companyId);
        entity.setProjectId(projectId);
        entity.setTaskName(param.getTaskName());
        entity.setExecCount(param.getExecCount());
        entity.setExecWeek(param.getExecWeek());
        entity.setRouteId(param.getRouteId());
        entity.setTaskType(param.getTaskType());
        entity.setStartDate(param.getStartDate());
        entity.setEndDate(param.getEndDate());
        entity.setTeamId(param.getTeamId());
        entity.setExecBys(param.getExecBys());
        entity.setExecStartTime(param.getExecStartTime());
        entity.setExecEndTime(param.getExecEndTime());
        entity.setRemarks(param.getRemarks());
        entity.setIsRecordLocation(param.getIsRecordLocation());
        entity.setUpdateBy(SessionUtil.getUserId());
        this.updateById(entity);

        createTask(entity, true);
    }

    /**
     * 创建本周正式任务
     * @param plan
     * @param isUpdate
     */
    public void createTask(PatrolTaskPlan plan, boolean isUpdate){
        List<PatrolTaskPlanWeekDetailVO> patrolTaskPlans = this.baseMapper.findByNowEffect(plan.getEndDate()
        ,plan.getExecStartTime()
        ,plan.getExecEndTime()
        ,plan.getExecCount()
        ,plan.getExecWeek());
        if(isUpdate){
            //删除该任务巡检项明细快照
            taskItemChildService.delByUnFinishTask(plan.getId());
            //删除该任务巡检项快照
            taskItemService.delByUnFinishTask(plan.getId());
            //删除该任务巡检点快照
            taskPointService.delByUnFinishTask(plan.getId());
            //删除该任务巡检线路快照
            taskRouteService.delByUnFinishTask(plan.getId());
            //删除该任务快照
            taskNormalService.delByUnFinishTask(plan.getId());
        }
        log.debug("----------start-------");
        patrolTaskPlans.forEach(patrolTaskPlan -> {
            //插入正式执行任务
            patrolTaskPlan.setProjectId(plan.getProjectId());
            patrolTaskPlan.setCompanyId(plan.getCompanyId());
            patrolTaskPlan.setId(plan.getId());
            patrolTaskPlan.setTaskName(plan.getTaskName());
            patrolTaskPlan.setTaskType(plan.getTaskType());
            patrolTaskPlan.setRouteId(plan.getRouteId());
            patrolTaskPlan.setTeamId(plan.getTeamId());
            patrolTaskPlan.setExecBys(plan.getExecBys());
            patrolTaskPlan.setIsRecordLocation(plan.getIsRecordLocation());
            patrolTaskPlan.setExecStartTime(plan.getExecStartTime());
            patrolTaskPlan.setExecEndTime(plan.getExecEndTime());
            patrolTaskPlan.setRemarks(plan.getRemarks());
            patrolTaskPlan.setExecCount(plan.getExecCount());
            patrolTaskPlan.setCreateBy(plan.getCreateBy());

            taskNormalService.insertByPlans(patrolTaskPlan);
        });
        log.debug("----------end-------");
        //插入线路快照
        taskRouteService.insertAll();

        //插入点位快照
        taskPointService.insertAll();

        //插入项目快照
        taskItemService.insertAll();

        //插入巡检项子表快照
        taskItemChildService.insertAll();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void del(Long planId){
        Long companyId = SessionUtil.getCompanyId();
        Long projectId = SessionUtil.getProjectId();

        QueryWrapper<PatrolTaskPlan> wrapper = new QueryWrapper<>();
        PatrolTaskPlan data = new PatrolTaskPlan();
        data.setDelFlag(DelFlagEnum.NORMAL.getCode());
        data.setCompanyId(companyId);
        data.setProjectId(projectId);
        data.setId(planId);
        wrapper.setEntity(data);
        PatrolTaskPlan entity = this.getOne(wrapper);
        if (entity == null) {
            throw new IllegalArgumentException("任务不存在");
        }

        // 删除
        entity = new PatrolTaskPlan();
        entity.setId(planId);
        entity.setUpdateBy(SessionUtil.getUserId());
        entity.setDelFlag(DelFlagEnum.DELETED.getCode());
        this.updateById(entity);

        //删除该任务巡检项明细快照
        taskItemChildService.delByUnFinishTask(entity.getId());
        //删除该任务巡检项快照
        taskItemService.delByUnFinishTask(entity.getId());
        //删除该任务巡检点快照
        taskPointService.delByUnFinishTask(entity.getId());
        //删除该任务巡检线路快照
        taskRouteService.delByUnFinishTask(entity.getId());
        //删除该任务快照
        taskNormalService.delByUnFinishTask(entity.getId());
    }

    public PatrolTaskPlanDetailVO detail(Long planId){
        return this.baseMapper.findByTaskPlanId(SessionUtil.getCompanyId()
                                        , SessionUtil.getProjectId()
                                        , planId);
    }

    /**
     * 查找上周需要生成的计划任务
     * @return
     */
    @Override
    public List<PatrolTaskPlanWeekDetailVO> findByEffect(){

        return this.baseMapper.findByEffect();
    }

    /**
     * 查找当事人的计划任务
     * @param userId
     * @return
     */
    @Override
    public List<PatrolTaskPlan> findTaskPlanByUser(Long userId) {
        return this.baseMapper.findTaskPlanByProjectAndUser(userId);
    }
}
